package com.zzz.codegen.config;

import com.zzz.codegen.constant.GenTypeConst;
import com.zzz.codegen.template.ITemplate;
import com.zzz.codegen.template.impl.EnjoyTemplate;
import com.zzz.codegen.util.CodegenUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

import java.io.File;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;

@Accessors(chain = true)
@Setter
@Getter
public class GlobalConfig implements Serializable {

    private static final long serialVersionUID = 8541606595570601831L;

    private ITemplate template = new EnjoyTemplate();

    private Map<String, TemplateConfig> configMap = new LinkedHashMap<>();

    private GroupConfig group = new GroupConfig();

    public GlobalConfig() {
        //按照顺序加载配置。如 Mapper.java 中会使用 Entity 信息，所以 Entity 在前面。
        registerTemplateConfig(buildEntityConfig());
        registerTemplateConfig(buildMapperConfig());
        registerTemplateConfig(buildSimpleServiceConfig());
        registerTemplateConfig(buildControllerConfig());
        registerTemplateConfig(buildMapperXmlConfig());
    }

    public void registerTemplateConfig(TemplateConfig config) {
        configMap.put(config.getGenType(), config);
    }

    public TemplateConfig getEntityConfig() {
        return getTemplateConfig(GenTypeConst.ENTITY);
    }

    public TemplateConfig getMapperConfig() {
        return getTemplateConfig(GenTypeConst.MAPPER);
    }

    public TemplateConfig getMapperXmlConfig() {
        return getTemplateConfig(GenTypeConst.MAPPER_XML);
    }

    public TemplateConfig getServiceConfig() {
        return getTemplateConfig(GenTypeConst.SERVICE);
    }

    public TemplateConfig getSimpleServiceConfig() {
        return getTemplateConfig(GenTypeConst.SIMPLE_SERVICE);
    }

    public TemplateConfig getServiceImplConfig() {
        return getTemplateConfig(GenTypeConst.SERVICE_IMPL);
    }

    public TemplateConfig getControllerConfig() {
        return getTemplateConfig(GenTypeConst.CONTROLLER);
    }

    public TemplateConfig getTemplateConfig(String genType) {
        return configMap.get(genType);
    }

    public static TemplateConfig buildEntityConfig() {
        return new TemplateConfig().setGenType(GenTypeConst.ENTITY)
                .setFileBuilder(javaFileBuilder)
                .setClassSuffix("Entity")
                .setPackagePath("com.test.entity")
                .setTemplatePath("templates/custom/entity.tpl")
                ;
    }

    public static TemplateConfig buildSimpleServiceConfig() {
        return new TemplateConfig().setGenType(GenTypeConst.SIMPLE_SERVICE)
                .setFileBuilder(javaFileBuilder)
                .setClassSuffix("SimpleService")
                .setPackagePath("com.test.service")
                .setClassImports(new String[]{"com.mybatisflex.core.service.IService", "java.io.Serializable"})
                .setInterfacesName("IService")
                .setTemplatePath("templates/custom/simpleService.tpl")
                ;
    }

    public static TemplateConfig buildControllerConfig() {
        return new TemplateConfig().setGenType(GenTypeConst.CONTROLLER)
                .setFileBuilder(javaFileBuilder)
                .setClassSuffix("Controller")
                .setPackagePath("com.test.controller")
                .setTemplatePath("templates/custom/controller.tpl")
                ;
    }

    public static TemplateConfig buildMapperConfig() {
        return new TemplateConfig().setGenType(GenTypeConst.MAPPER)
                .setFileBuilder(javaFileBuilder)
                .setClassSuffix("Mapper")
                .setPackagePath("com.test.mapper")
                .setClassImports(new String[]{"com.mybatisflex.core.BaseMapper"})
                .setSuperClassName("BaseMapper")
                .setTemplatePath("templates/custom/mapper.tpl")
                ;
    }

    public static TemplateConfig buildMapperXmlConfig() {
        return new TemplateConfig().setGenType(GenTypeConst.MAPPER_XML)
                .setFileBuilder(xmlFileBuilder)
                .setClassSuffix("Mapper")
                .setPackagePath("mapper")
                .setPackagePath(System.getProperty("user.dir").concat("/src/main/resources/mapper"))
                .setTemplatePath("templates/custom/mapperXml.tpl")
                ;
    }

    public static Function<TemplateConfig, File> javaFileBuilder = CodegenUtil::buildJavaFile;

    /**
     * 组装 xml 文件路径
     */
    public static Function<TemplateConfig, File> xmlFileBuilder = CodegenUtil::buildXmlFile;
}
